package com.office.automate.service.impl.administration;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.office.automate.administration.data.validator.BranchDataValidator;
import com.office.automate.administration.data.validator.DivisionDataValidator;
import com.office.automate.administration.data.validator.PublicHolidayDataValidator;
import com.office.automate.administration.data.validator.SecurityLevelDataValidator;
import com.office.automate.dataaccess.def.administration.BranchDao;
import com.office.automate.dataaccess.def.administration.DivisionDao;
import com.office.automate.dataaccess.def.administration.PublicHolidayDao;
import com.office.automate.dataaccess.def.administration.SecurityLevelDao;
import com.office.automate.dataaccess.impl.administration.BranchDaoImplementer;
import com.office.automate.dataaccess.impl.administration.DivisionDaoImplementer;
import com.office.automate.dataaccess.impl.administration.PublicHolidayDaoImplementer;
import com.office.automate.dataaccess.impl.administration.SecurityLevelDaoImplementer;
import com.office.automate.dataaccess.impl.user.EmployeeDaoImplementer;
import com.office.automate.exception.framework.FrontierVisibleException;
import com.office.automate.model.administration.Branch;
import com.office.automate.model.administration.Division;
import com.office.automate.model.administration.PublicHoliday;
import com.office.automate.model.administration.SecurityLevel;
import com.office.automate.service.def.administration.AdministrationService;

public class AdministrationServiceImplementer implements AdministrationService {

	private SecurityLevelDao securityLevelDao = new SecurityLevelDaoImplementer();
	private BranchDao branchDao = new BranchDaoImplementer();
	private DivisionDao divisionDao = new DivisionDaoImplementer();
	private PublicHolidayDao publicHolidayDao = new PublicHolidayDaoImplementer();
	private SecurityLevelDataValidator securityLevelDataValidator = new SecurityLevelDataValidator();
	private BranchDataValidator branchDataValidator = new BranchDataValidator();
	private DivisionDataValidator divisionValidator = new DivisionDataValidator();
	private PublicHolidayDataValidator publicHolidayDataValidator = new PublicHolidayDataValidator();
	private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

	public HashMap<String, FrontierVisibleException> validateSecurityLevelDetails(SecurityLevel aSecurityLevel) throws FrontierVisibleException {

		HashMap<String, FrontierVisibleException> fieldValidationErrors = null;

		securityLevelDataValidator.validateNewSecurityLevelDetails(aSecurityLevel);

		if (securityLevelDataValidator.isValidationErrorsExist()) {
			fieldValidationErrors = securityLevelDataValidator.getFieldValidationErrors();
		}
		return fieldValidationErrors;
	}

	public SecurityLevel addSecurityLevel(SecurityLevel aSecurityLevel) throws FrontierVisibleException {
		securityLevelDao.persistSecurityLevelDetails(aSecurityLevel);

		return aSecurityLevel;
	}

	public List<SecurityLevel> getAvailableSecurityLevels() throws FrontierVisibleException {

		return securityLevelDao.getAvailableSecurityLevels();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<List> getAvailableSecurityLevelsPage(int aStartingIndex, int aNumberOfRecords) throws FrontierVisibleException {
		List<List> aSecurityLevelList = new ArrayList<List>();

		List<SecurityLevel> securityLevels = securityLevelDao.getAvailableSecurityLevelsPage(aStartingIndex, aNumberOfRecords);
	
		for (SecurityLevel seclvl :securityLevels) {
			List aSecurityLevelDataRow = new ArrayList();
			aSecurityLevelDataRow.add(seclvl.getSecurityLevelId());
			aSecurityLevelDataRow.add(seclvl.getSecurityLevelDescription());
			aSecurityLevelList.add(aSecurityLevelDataRow);
		}
		return aSecurityLevelList;
	}

	public void deleteSecurityLevel(SecurityLevel aSecurityLevel) throws FrontierVisibleException {
		
		securityLevelDao.deleteSecurityLevel(aSecurityLevel);
	}

	public int getAvailableSecurityLevelRecordCount() throws FrontierVisibleException {

		return securityLevelDao.getAvailableSecurityLevelRecordCount();
	}

	public int getAvailableBranchDetailRecordCount() throws FrontierVisibleException {

		return branchDao.getAvailableBranchDetailRecordCount();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<List> getAvailableBranchesPage(int aStartingIndex, int aNumberOfRecords) throws FrontierVisibleException {
		List<List> aBrancheList = new ArrayList<List>();

		List<Branch> branches = branchDao.getAvailableBranchesPage(aStartingIndex, aNumberOfRecords);
	
		for (Branch branch :branches) {
			List aBranchDataRow = new ArrayList();
			aBranchDataRow.add(branch.getBranchId());
			aBranchDataRow.add(branch.getDescription());
			aBranchDataRow.add(branch.getLocation());
			aBranchDataRow.add(new EmployeeDaoImplementer().getEmployeeName(branch.getManagerOrSupervisorId()));
			aBrancheList.add(aBranchDataRow);
		}
		return aBrancheList;
	}

	public HashMap<String, FrontierVisibleException> validateBranchDetails(Branch aBranch) throws FrontierVisibleException {
		HashMap<String, FrontierVisibleException> fieldValidationErrors = null;

		branchDataValidator.validateNewBranchDetails(aBranch);

		if (branchDataValidator.isValidationErrorsExist()) {
			fieldValidationErrors = branchDataValidator.getFieldValidationErrors();
		}
		return fieldValidationErrors;
	}

	public Branch addBranch(Branch aBranch) throws FrontierVisibleException {

		aBranch = branchDao.persistBranchDetails(aBranch);

		return aBranch;
	}

	public void deleteBranch(Branch aBranch) throws FrontierVisibleException {
		branchDao.deleteBranch(aBranch);
	}

	public HashMap<String, FrontierVisibleException> validateDivisionDetails(Division aDivision) throws FrontierVisibleException {
		HashMap<String, FrontierVisibleException> fieldValidationErrors = null;

		divisionValidator.validateNewDivisionDetails(aDivision);

		if (divisionValidator.isValidationErrorsExist()) {
			fieldValidationErrors = divisionValidator.getFieldValidationErrors();
		}
		return fieldValidationErrors;
	}

	public Division addDivision(Division aDivision) throws FrontierVisibleException {

		aDivision = divisionDao.persistDivisionDetails(aDivision);

		return aDivision;
	}

	public void deleteDivision(Division aDivision) throws FrontierVisibleException {
		divisionDao.deleteDivision(aDivision);
		
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<List> getAvailableDivisionsPage(int aStartingIndex, int aNumberOfRecords) throws FrontierVisibleException {
		List<List> aDivisionList = new ArrayList<List>();

		List<Division> divisions = divisionDao.getAvailableDivisionsPage(aStartingIndex, aNumberOfRecords);
	
		for (Division division :divisions) {
			List aDivisionDataRow = new ArrayList();
			aDivisionDataRow.add(division.getDivisionId());
			aDivisionDataRow.add(division.getName());
			aDivisionDataRow.add(division.getDescription());
			aDivisionList.add(aDivisionDataRow);
		}
		return aDivisionList;
	}

	public int getAvailableDivisionDetailRecordCount() throws FrontierVisibleException {
		return divisionDao.getAvailableDivisionDetailRecordCount();
	}

	public List<Branch> getAvailableBranches() throws FrontierVisibleException {
		return branchDao.getAvailableBranches();
	}

	public List<Division> getAvailableDivisions() throws FrontierVisibleException {
		return divisionDao.getAvailableDivisions();
	}

	public HashMap<String, FrontierVisibleException> validatePublicHolidayDetails(PublicHoliday publicHoliday) throws FrontierVisibleException {
		HashMap<String, FrontierVisibleException> fieldValidationErrors = null;

		publicHolidayDataValidator.validatePublicHolidayDetails(publicHoliday);

		if (publicHolidayDataValidator.isValidationErrorsExist()) {
			fieldValidationErrors = publicHolidayDataValidator.getFieldValidationErrors();
		}
		return fieldValidationErrors;
	}

	public PublicHoliday addPublicHoliday(PublicHoliday publicHoliday) throws FrontierVisibleException {
		publicHoliday = publicHolidayDao.persistHolidayDetails(publicHoliday);
		return publicHoliday;
	}

	public int getAvailablePublicHolidayRecordCount() throws FrontierVisibleException {
		return publicHolidayDao.getAvailablePublicHolidayRecordCount();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<List> getAvailablePublicHolidayPage(int aStartingIndex, int aNumberOfRecords) throws FrontierVisibleException {
		List<List> aPublicHolidayList = new ArrayList<List>();

		List<PublicHoliday> publicHolidays = publicHolidayDao.getAvailablePublicHolidayPage(aStartingIndex, aNumberOfRecords);
	
		for (PublicHoliday publicHoliday :publicHolidays) {
			List aPublicHolidayDataRow = new ArrayList();
			aPublicHolidayDataRow.add(formatter.format(publicHoliday.getHolidayDate()));
			aPublicHolidayDataRow.add(publicHoliday.getHolidayType());
			aPublicHolidayDataRow.add(publicHoliday.getHolidayDescription());
			aPublicHolidayDataRow.add(publicHoliday.getHolidayEntryId());
			aPublicHolidayList.add(aPublicHolidayDataRow);
		}
		return aPublicHolidayList;
	}

	public void deletePublicHoliday(long holidayEntryId) throws FrontierVisibleException {
		PublicHoliday publicHoliday = new PublicHoliday();
		publicHoliday.setHolidayEntryId(holidayEntryId);
		publicHolidayDao.deletePublicHoliday(publicHoliday);
		
	}
}
